//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.1
#include "dma_bsp.h"
#include <string.h>

/*DMA总管理结构体*/
typedef struct
{
    WHT_DMA_Stream_enum Stream;//DMA通道名字
    WHT_DMA_Info_t Info;       //所有标志,提供给外部
    void (*IT_Callback)(void); //通道回调函数
}WHT_Data_t;

static WHT_Data_t WHT_DMA1_Stream_0 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream0_BASE};
static WHT_Data_t WHT_DMA1_Stream_1 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream1_BASE};
static WHT_Data_t WHT_DMA1_Stream_2 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream2_BASE};
static WHT_Data_t WHT_DMA1_Stream_3 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream3_BASE};
static WHT_Data_t WHT_DMA1_Stream_4 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream4_BASE};
static WHT_Data_t WHT_DMA1_Stream_5 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream5_BASE};
static WHT_Data_t WHT_DMA1_Stream_6 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream6_BASE};
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F410xx) || defined(STM32F401xx)\
    || defined(STM32F411xE) || defined(STM32F469_479xx) || defined(STM32F446xx) || defined(STM32F412xG) || defined(STM32F413_423xx)
static WHT_Data_t WHT_DMA1_Stream_7 = {.Stream = (WHT_DMA_Stream_enum)DMA1_Stream7_BASE};
static WHT_Data_t WHT_DMA2_Stream_0 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream0_BASE};
static WHT_Data_t WHT_DMA2_Stream_1 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream1_BASE};
static WHT_Data_t WHT_DMA2_Stream_2 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream2_BASE};
static WHT_Data_t WHT_DMA2_Stream_3 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream3_BASE};
static WHT_Data_t WHT_DMA2_Stream_4 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream4_BASE};
static WHT_Data_t WHT_DMA2_Stream_5 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream5_BASE};
static WHT_Data_t WHT_DMA2_Stream_6 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream6_BASE};
static WHT_Data_t WHT_DMA2_Stream_7 = {.Stream = (WHT_DMA_Stream_enum)DMA2_Stream7_BASE};
#endif

#define WHT_DMA     ((WHT_Data_t*)config->Private_Data)//简化操作


/*DMA中断优先级配置*/
static void NVIC_Config_uration(unsigned char NVIC_IRQStream)
{
	NVIC_SetPriority(NVIC_IRQStream, 15);
	NVIC_EnableIRQ(NVIC_IRQStream);
}
/*DMA注册*/
static ErrorStatus WHT_DMA_BSP_Register(const WHT_DMA_Config_t* config)
{
    if ((WHT_DMA != NULL) && (config->Info != NULL))//之前注册过了
        return SUCCESS;
    
    switch ((unsigned int)config->Stream)
    {
    case DMA1_Stream0_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_0; NVIC_Config_uration(DMA1_Stream0_IRQn); break;
    case DMA1_Stream1_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_1; NVIC_Config_uration(DMA1_Stream1_IRQn); break;
    case DMA1_Stream2_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_2; NVIC_Config_uration(DMA1_Stream2_IRQn); break;
    case DMA1_Stream3_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_3; NVIC_Config_uration(DMA1_Stream3_IRQn); break;
    case DMA1_Stream4_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_4; NVIC_Config_uration(DMA1_Stream4_IRQn); break;
    case DMA1_Stream5_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_5; NVIC_Config_uration(DMA1_Stream5_IRQn); break;
    case DMA1_Stream6_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_6; NVIC_Config_uration(DMA1_Stream6_IRQn); break;
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F410xx) || defined(STM32F401xx)\
    || defined(STM32F411xE) || defined(STM32F469_479xx) || defined(STM32F446xx) || defined(STM32F412xG) || defined(STM32F413_423xx)
    case DMA1_Stream7_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA1_Stream_7; NVIC_Config_uration(DMA1_Stream7_IRQn); break;
    case DMA2_Stream0_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_0; NVIC_Config_uration(DMA2_Stream0_IRQn); break;
    case DMA2_Stream1_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_1; NVIC_Config_uration(DMA2_Stream1_IRQn); break;
    case DMA2_Stream2_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_2; NVIC_Config_uration(DMA2_Stream2_IRQn); break;
    case DMA2_Stream3_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_3; NVIC_Config_uration(DMA2_Stream3_IRQn); break;
    case DMA2_Stream4_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_4; NVIC_Config_uration(DMA2_Stream4_IRQn); break;
    case DMA2_Stream5_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_5; NVIC_Config_uration(DMA2_Stream5_IRQn); break;
    case DMA2_Stream6_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_6; NVIC_Config_uration(DMA2_Stream6_IRQn); break;
    case DMA2_Stream7_BASE:((WHT_DMA_Config_t*)config)->Private_Data = &WHT_DMA2_Stream_7; NVIC_Config_uration(DMA2_Stream7_IRQn); break;
#endif
    default:return ERROR;
    }

    /////////////////////WHT_DMA->Stream = config->Stream;
    ((WHT_DMA_Config_t*)config)->Info = &WHT_DMA->Info;
    WHT_DMA->Info.Mount_Count++;
    RCC_AHB1PeriphClockCmd(config->Stream >= DMA2_Stream0_BASE ? RCC_AHB1Periph_DMA2 : RCC_AHB1Periph_DMA1, ENABLE);//Open DMA Clock For AHB
    return SUCCESS;
}
/*DMA配置*/
static void WHT_DMA_BSP_Config(const WHT_DMA_Config_t* config)
{
    if ((WHT_DMA == NULL) || (config->Info == NULL))
        return;

    WHT_DMA->Info.State = TRx_TS;
    WHT_DMA->IT_Callback = config->IT_Callback;
    
    DMA_DeInit((DMA_Stream_TypeDef *)WHT_DMA->Stream);                                          //Reset DMA
    DMA_Init((DMA_Stream_TypeDef*)WHT_DMA->Stream, ((WHT_DMA_Config_t*)config)->DMA_InitStruct);//Init Config DMA Stream
    if (config->DMA_InitStruct->DMA_Mode == DMA_Mode_Circular)                                  //循环传输模式
    {
        DMA_ITConfig((DMA_Stream_TypeDef*)WHT_DMA->Stream, DMA_IT_TC | DMA_IT_HT, DISABLE);//Off TC HT DMA Interrupt
        DMA_ITConfig((DMA_Stream_TypeDef*)WHT_DMA->Stream, DMA_IT_TE | DMA_IT_DME | DMA_IT_FE, ENABLE);//Open TE DMA Interrupt
    }
    else
        DMA_ITConfig((DMA_Stream_TypeDef*)WHT_DMA->Stream, DMA_IT_TC | DMA_IT_HT | DMA_IT_TE | DMA_IT_DME | DMA_IT_FE, ENABLE);//open All DMA IT Stream
    
    DMA_Cmd((DMA_Stream_TypeDef*)WHT_DMA->Stream, ENABLE);                    //Open DMA Stream
    while (DMA_GetCmdStatus((DMA_Stream_TypeDef*)WHT_DMA->Stream) == DISABLE);//确保DMA数据流配置完成
}

/*DMA获取当前数据个数*/
static unsigned short WHT_DMA_BSP_Get_Curr_Data_Count(const WHT_DMA_Config_t* config)
{
    if (WHT_DMA == NULL)
        return (unsigned short)65535;
    else
        return DMA_GetCurrDataCounter((DMA_Stream_TypeDef*)WHT_DMA->Stream);
}
/*DMA关闭*/
static void WHT_DMA_BSP_Close(const WHT_DMA_Config_t* config)
{
    if (WHT_DMA)
    {
        DMA_DeInit((DMA_Stream_TypeDef *)WHT_DMA->Stream);//Reset DMA
        WHT_DMA->Info.State = TRx_TC;
        WHT_DMA->Info.BSP_Mutex = RESET;
    }
}

/*DMA检查空闲数据流并上锁 STM32F1/F4 DMA1不支持内存拷贝*/
static ErrorStatus WHT_DMA_BSP_Lock_Idle_Streamx(const WHT_DMA_Config_t* config)
{
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F410xx) || defined(STM32F401xx)\
    || defined(STM32F411xE) || defined(STM32F469_479xx) || defined(STM32F446xx) || defined(STM32F412xG) || defined(STM32F413_423xx)
    unsigned char Number;
    WHT_Data_t* DMAx_Streamx[] =
    {
        &WHT_DMA2_Stream_0,
        &WHT_DMA2_Stream_1,
        &WHT_DMA2_Stream_2,
        &WHT_DMA2_Stream_3,
        &WHT_DMA2_Stream_4,
        &WHT_DMA2_Stream_5,
        &WHT_DMA2_Stream_6,
        &WHT_DMA2_Stream_7,
    };

    for (Number = 0; Number < sizeof(DMAx_Streamx) / sizeof(DMAx_Streamx[0]); Number++)//寻找未被注册过并且未使用过的
    {
        if ((DMAx_Streamx[Number]->Info.Mount_Count == RESET) && (DMAx_Streamx[Number]->Info.BSP_Mutex == RESET))
        {
            DMAx_Streamx[Number]->Info.BSP_Mutex = SET;
            goto Game_Over;
        }
    }
    for (Number = 0; Number < sizeof(DMAx_Streamx) / sizeof(DMAx_Streamx[0]); Number++)//寻找所有的
    {
        if (DMAx_Streamx[Number]->Info.BSP_Mutex == RESET)
        {
            DMAx_Streamx[Number]->Info.BSP_Mutex = SET;
            goto Game_Over;
        }
    }
    return ERROR;

    Game_Over:
        DMAx_Streamx[Number]->Info.Mount_Count++;//由调用者释放!!!
        ((WHT_DMA_Config_t*)config)->Stream = DMAx_Streamx[Number]->Stream;
        ((WHT_DMA_Config_t*)config)->IT_Callback = NULL;
        ((WHT_DMA_Config_t*)config)->Info = &DMAx_Streamx[Number]->Info;
        ((WHT_DMA_Config_t*)config)->Private_Data = DMAx_Streamx[Number];
        
        RCC_AHB1PeriphClockCmd(config->Stream >= DMA2_Stream0_BASE ? RCC_AHB1Periph_DMA2 : RCC_AHB1Periph_DMA1, ENABLE);//Open DMA Clock For AHB
        switch ((unsigned int)config->Stream)
        {
        case DMA2_Stream0_BASE:NVIC_Config_uration(DMA2_Stream0_IRQn); break;
        case DMA2_Stream1_BASE:NVIC_Config_uration(DMA2_Stream1_IRQn); break;
        case DMA2_Stream2_BASE:NVIC_Config_uration(DMA2_Stream2_IRQn); break;
        case DMA2_Stream3_BASE:NVIC_Config_uration(DMA2_Stream3_IRQn); break;
        case DMA2_Stream4_BASE:NVIC_Config_uration(DMA2_Stream4_IRQn); break;
        case DMA2_Stream5_BASE:NVIC_Config_uration(DMA2_Stream5_IRQn); break;
        case DMA2_Stream6_BASE:NVIC_Config_uration(DMA2_Stream6_IRQn); break;
        case DMA2_Stream7_BASE:NVIC_Config_uration(DMA2_Stream7_IRQn); break;
        }
        return SUCCESS;
#else
    return  ERROR;
#endif
}
/*DMA内存拷贝*/
void WHT_DMA_BSP_Memcpy(void* _Dst, void const* _Src, unsigned int _Size)
{
    WHT_DMA_Config_t Config;
    unsigned int Data_Size_4x_Number;

	if (_Size > 65535 * sizeof(unsigned int) || (_Size < sizeof(unsigned int)))//for max 262140 Byte
	{
		memcpy(_Dst, _Src, _Size);
		return;
	}
    if (WHT_DMA_BSP_Lock_Idle_Streamx(&Config) == ERROR)
    {
        memcpy(_Dst, _Src, _Size);
        return;
    }

	Data_Size_4x_Number = _Size >> 2;//4倍的个数
	if (_Size & 0x03)                //4倍的余数
		memcpy(((unsigned int*)_Dst) + Data_Size_4x_Number, ((unsigned int*)_Src) + Data_Size_4x_Number, _Size & 0x03);
	
 	DMA_InitTypeDef DMA_InitStruct =
	{
        .DMA_Channel            = DMA_Channel_0,              //DMA通道
        .DMA_PeripheralBaseAddr = (unsigned int)_Dst,         //目的基地址
        .DMA_Memory0BaseAddr    = (unsigned int)_Src,         //源基地址
        .DMA_DIR                = DMA_DIR_MemoryToMemory,     //M->M
        .DMA_BufferSize         = Data_Size_4x_Number,        //传输个数
        .DMA_PeripheralInc      = DMA_PeripheralInc_Enable,   //目的地址递增
        .DMA_MemoryInc          = DMA_MemoryInc_Enable,       //源地址递增
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word,//目的数据大小为字
        .DMA_MemoryDataSize     = DMA_MemoryDataSize_Word,    //源数据大小为字
        .DMA_Mode               = DMA_Mode_Normal,            //单次传输模式
        .DMA_Priority           = DMA_Priority_Low,           //优先级最低
        .DMA_FIFOMode           = DMA_FIFOMode_Disable,       //FIFO模式
        .DMA_FIFOThreshold      = DMA_FIFOThreshold_1QuarterFull,//FIFO阈值
        .DMA_MemoryBurst        = DMA_MemoryBurst_Single,     //内存突发传输
        .DMA_PeripheralBurst    = DMA_PeripheralBurst_Single, //外设突发传输
	};

    Config.Info->State = TRx_TS;
    Config.Info->Mount_Count--;//这里给它手动减去

    DMA_Init((DMA_Stream_TypeDef*)Config.Stream, &DMA_InitStruct);                  //Init Config DMA Channel
    DMA_ITConfig((DMA_Stream_TypeDef*)Config.Stream, DMA_IT_TC | DMA_IT_TE, ENABLE);//Open TC TE DMA Interrupt
    DMA_Cmd((DMA_Stream_TypeDef*)Config.Stream, ENABLE);                            //Open DMA Channel
}
/*全局常量*/
const WHT_DMA_BSP_t WHT_DMA_BSP =
{
    .WHT_Register            = WHT_DMA_BSP_Register,
    .WHT_Config              = WHT_DMA_BSP_Config,
    .WHT_Get_Curr_Data_Count = WHT_DMA_BSP_Get_Curr_Data_Count,
    .WHT_Close               = WHT_DMA_BSP_Close,
};



typedef struct
{
    unsigned int DMA_IT_TCIFx; //流传输完成中断
    unsigned int DMA_IT_HTIFx; //流传输过半完成中断
    unsigned int DMA_IT_TEIFx; //流传输错误中断
    unsigned int DMA_IT_DMEIFx;//流直接模式错误中断
    unsigned int DMA_IT_FEIFx; //流FIFO错误中断
}WHT_DMA_IT_Event_t;


/*DMA中断回调函数*/
static void WHT_DMA_BSP_DMA_Stream_IRQHandler(WHT_Data_t* dma_stream, const WHT_DMA_IT_Event_t* dma_it_event)
{
    if (DMA_GetITStatus((DMA_Stream_TypeDef*)dma_stream->Stream, dma_it_event->DMA_IT_HTIFx) == SET)
    {
        dma_stream->Info.State = TRx_HT;
        DMA_ClearITPendingBit((DMA_Stream_TypeDef*)dma_stream->Stream, dma_it_event->DMA_IT_HTIFx);
    }
    else if (DMA_GetITStatus((DMA_Stream_TypeDef*)dma_stream->Stream, dma_it_event->DMA_IT_TCIFx) == SET)
    {
        dma_stream->Info.State = TRx_TC;
        goto GameOver;
    }
    else //错误了
    {
        dma_stream->Info.State = TRx_TE;
        goto GameOver;
    }
    return;
    GameOver:
    //对于向外设发送数据,注意最后一个数据此时在发送过程中
    DMA_Cmd((DMA_Stream_TypeDef*)dma_stream->Stream, DISABLE);
    DMA_ClearITPendingBit((DMA_Stream_TypeDef*)dma_stream->Stream, dma_it_event->DMA_IT_TCIFx
                                                                 | dma_it_event->DMA_IT_TEIFx
                                                                 | dma_it_event->DMA_IT_DMEIFx
                                                                 | dma_it_event->DMA_IT_FEIFx);
    if (dma_stream->IT_Callback != NULL)
    {
        dma_stream->IT_Callback();
        dma_stream->IT_Callback = NULL;
    }
    dma_stream->Info.BSP_Mutex = RESET;//自解锁
}

/*DMA1数据流0中断服务程序*/
void DMA1_Stream0_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF0,
        .DMA_IT_HTIFx = DMA_IT_HTIF0,
        .DMA_IT_TEIFx = DMA_IT_TEIF0,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF0,
        .DMA_IT_FEIFx = DMA_IT_FEIF0,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_0, &WHT_DMA_IT_Event);
}
/*DMA1数据流1中断服务程序*/
void DMA1_Stream1_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF1,
        .DMA_IT_HTIFx = DMA_IT_HTIF1,
        .DMA_IT_TEIFx = DMA_IT_TEIF1,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF1,
        .DMA_IT_FEIFx = DMA_IT_FEIF1,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_1, &WHT_DMA_IT_Event);
}
/*DMA1数据流2中断服务程序*/
void DMA1_Stream2_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF2,
        .DMA_IT_HTIFx = DMA_IT_HTIF2,
        .DMA_IT_TEIFx = DMA_IT_TEIF2,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF2,
        .DMA_IT_FEIFx = DMA_IT_FEIF2,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_2, &WHT_DMA_IT_Event);
}
/*DMA1数据流3中断服务程序*/
void DMA1_Stream3_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF3,
        .DMA_IT_HTIFx = DMA_IT_HTIF3,
        .DMA_IT_TEIFx = DMA_IT_TEIF3,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF3,
        .DMA_IT_FEIFx = DMA_IT_FEIF3,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_3, &WHT_DMA_IT_Event);
}
/*DMA1数据流4中断服务程序*/
void DMA1_Stream4_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF4,
        .DMA_IT_HTIFx = DMA_IT_HTIF4,
        .DMA_IT_TEIFx = DMA_IT_TEIF4,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF4,
        .DMA_IT_FEIFx = DMA_IT_FEIF4,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_4, &WHT_DMA_IT_Event);
}
/*DMA1数据流5中断服务程序*/
void DMA1_Stream5_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF5,
        .DMA_IT_HTIFx = DMA_IT_HTIF5,
        .DMA_IT_TEIFx = DMA_IT_TEIF5,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF5,
        .DMA_IT_FEIFx = DMA_IT_FEIF5,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_5, &WHT_DMA_IT_Event);
}
/*DMA1数据流6中断服务程序*/
void DMA1_Stream6_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF6,
        .DMA_IT_HTIFx = DMA_IT_HTIF6,
        .DMA_IT_TEIFx = DMA_IT_TEIF6,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF6,
        .DMA_IT_FEIFx = DMA_IT_FEIF6,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_6, &WHT_DMA_IT_Event);
}


#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F410xx) || defined(STM32F401xx)\
    || defined(STM32F411xE) || defined(STM32F469_479xx) || defined(STM32F446xx) || defined(STM32F412xG) || defined(STM32F413_423xx)
/*DMA1数据流7中断服务程序*/
void DMA1_Stream7_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF7,
        .DMA_IT_HTIFx = DMA_IT_HTIF7,
        .DMA_IT_TEIFx = DMA_IT_TEIF7,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF7,
        .DMA_IT_FEIFx = DMA_IT_FEIF7,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA1_Stream_7, &WHT_DMA_IT_Event);
}

/*DMA2数据流0中断服务程序*/
void DMA2_Stream0_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF0,
        .DMA_IT_HTIFx = DMA_IT_HTIF0,
        .DMA_IT_TEIFx = DMA_IT_TEIF0,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF0,
        .DMA_IT_FEIFx = DMA_IT_FEIF0,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_0, &WHT_DMA_IT_Event);
}
/*DMA2数据流1中断服务程序*/
void DMA2_Stream1_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF1,
        .DMA_IT_HTIFx = DMA_IT_HTIF1,
        .DMA_IT_TEIFx = DMA_IT_TEIF1,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF1,
        .DMA_IT_FEIFx = DMA_IT_FEIF1,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_1, &WHT_DMA_IT_Event);
}
/*DMA2数据流2中断服务程序*/
void DMA2_Stream2_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF2,
        .DMA_IT_HTIFx = DMA_IT_HTIF2,
        .DMA_IT_TEIFx = DMA_IT_TEIF2,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF2,
        .DMA_IT_FEIFx = DMA_IT_FEIF2,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_2, &WHT_DMA_IT_Event);
}
/*DMA2数据流3中断服务程序*/
void DMA2_Stream3_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF3,
        .DMA_IT_HTIFx = DMA_IT_HTIF3,
        .DMA_IT_TEIFx = DMA_IT_TEIF3,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF3,
        .DMA_IT_FEIFx = DMA_IT_FEIF3,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_3, &WHT_DMA_IT_Event);
}
/*DMA2数据流4中断服务程序*/
void DMA2_Stream4_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF4,
        .DMA_IT_HTIFx = DMA_IT_HTIF4,
        .DMA_IT_TEIFx = DMA_IT_TEIF4,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF4,
        .DMA_IT_FEIFx = DMA_IT_FEIF4,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_4, &WHT_DMA_IT_Event);
}
/*DMA2数据流5中断服务程序*/
void DMA2_Stream5_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF5,
        .DMA_IT_HTIFx = DMA_IT_HTIF5,
        .DMA_IT_TEIFx = DMA_IT_TEIF5,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF5,
        .DMA_IT_FEIFx = DMA_IT_FEIF5,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_5, &WHT_DMA_IT_Event);
}
/*DMA2数据流6中断服务程序*/
void DMA2_Stream6_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF6,
        .DMA_IT_HTIFx = DMA_IT_HTIF6,
        .DMA_IT_TEIFx = DMA_IT_TEIF6,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF6,
        .DMA_IT_FEIFx = DMA_IT_FEIF6,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_6, &WHT_DMA_IT_Event);
}
/*DMA2数据流7中断服务程序*/
void DMA2_Stream7_IRQHandler(void)
{
    static const WHT_DMA_IT_Event_t WHT_DMA_IT_Event =
    {
        .DMA_IT_TCIFx = DMA_IT_TCIF7,
        .DMA_IT_HTIFx = DMA_IT_HTIF7,
        .DMA_IT_TEIFx = DMA_IT_TEIF7,
        .DMA_IT_DMEIFx = DMA_IT_DMEIF7,
        .DMA_IT_FEIFx = DMA_IT_FEIF7,
    };
    WHT_DMA_BSP_DMA_Stream_IRQHandler(&WHT_DMA2_Stream_7, &WHT_DMA_IT_Event);
}
#endif
